<template>
  <div class="bx-anchor">
    <div class="bx-anchor__line"></div>
    <ul class="bx-anchor__list">
      <slot></slot>
    </ul>
  </div>
</template>

<script>
import { provide, ref, onMounted, onUnmounted } from 'vue'

export default {
  name: 'BxAnchor',
  props: {
    container: {
      type: [String, HTMLElement],
      default: () => window
    },
    bounds: {
      type: Number,
      default: 5
    },
    offset: {
      type: Number,
      default: 0
    }
  },
  setup(props) {
    const activeLink = ref('')
    const links = ref([])

    const registerLink = (link) => {
      links.value.push(link)
    }

    const unregisterLink = (link) => {
      links.value = links.value.filter(item => item !== link)
    }

    const getContainer = () => {
      if (typeof props.container === 'string') {
        return document.querySelector(props.container)
      }
      return props.container
    }

    const handleScroll = () => {
      const container = getContainer()
      const scrollTop = container === window ? document.documentElement.scrollTop || document.body.scrollTop : container.scrollTop

      let newActiveLink = ''
      for (let i = links.value.length - 1; i >= 0; i--) {
        const link = links.value[i]
        const targetElement = document.querySelector(link.href)
        if (targetElement) {
          const rect = targetElement.getBoundingClientRect()
          const elementTop = rect.top + scrollTop
          if (elementTop <= scrollTop + props.offset + props.bounds) {
            newActiveLink = link.href
            break
          }
        }
      }
      if (newActiveLink !== activeLink.value) {
        activeLink.value = newActiveLink
      }
    }

    onMounted(() => {
      const container = getContainer()
      if (container) {
        container.addEventListener('scroll', handleScroll)
        handleScroll() // Initial check
      }
    })

    onUnmounted(() => {
      const container = getContainer()
      if (container) {
        container.removeEventListener('scroll', handleScroll)
      }
    })

    provide('anchorContext', {
      activeLink,
      registerLink,
      unregisterLink,
      offset: props.offset,
      getContainer
    })

    return {
      activeLink
    }
  }
}
</script>

<style scoped>
.bx-anchor {
  position: relative;
  font-family: var(--bx-font-family);
  color: var(--bx-text-primary);
}

.bx-anchor__line {
  position: absolute;
  top: 0;
  left: 0;
  width: 2px;
  height: 100%;
  background-color: var(--bx-glass-border);
}

.bx-anchor__list {
  list-style: none;
  padding: 0;
  margin: 0;
  padding-left: 16px;
}
</style>

